package com.supermap.ar.unity.player;

import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.Window;

import com.unity3d.player.IUnityPlayerLifecycleEvents;
import com.unity3d.player.MultiWindowSupport;
import com.unity3d.player.UnityPlayer;

/**
 * 自定义Unity场景
 * 可将Unity场景添加至指定的ViewGroup，作为子视图
 * @author tanyx 2022/3/3
 * @version 1.0
 * <br/>SampleCode:<br/>
 * <code>
 *    //@Override<br/>
 *     protected void onCreate(Bundle savedInstanceState) {<br/>
 *         &nbsp;&nbsp;super.onCreate(savedInstanceState);<br/>
 *         &nbsp;&nbsp;setContentView(R.layout.activity_main2);<br/>
 *         &nbsp;&nbsp;Log.i("MainActivity", "onCreate: ");<br/>
 *         &nbsp;&nbsp;efView = findViewById(R.id.ef_view);<br/>
 *         &nbsp;&nbsp;bindViewGroup(<br/>
 *         &nbsp;&nbsp;&nbsp;&nbsp;//activity_main.xml的ViewGroup<br/>
 *         &nbsp;&nbsp;&nbsp;&nbsp;findViewById(R.id.p_layout));<br/>
 *     }
 * </code>
 **/
public class CustomUnityActivity extends Activity implements IUnityPlayerLifecycleEvents {

    private ViewGroup unityLayout;//unity视图容器
    private UnityPlayer mUnityPlayer;
    private boolean isAdded = false;

    /**
     * 绑定视图容器
     * @param layout
     */
    public void bindViewGroup(ViewGroup layout){
        this.unityLayout = layout;
        // 添加Unity视图
        unityLayout.addView(mUnityPlayer.getView());
        mUnityPlayer.requestFocus();
        isAdded = true;
    }

    /**
     * 获取unity播放器
     * @return
     */
    public UnityPlayer getUnityPlayer(){
        return mUnityPlayer;
    }

    //<editor-fold> 默认设置，大部分与unity官方示例一致，重写activity的部分方法，无需接口描述
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState);

        String cmdLine = updateUnityCommandLineArguments(getIntent().getStringExtra("unity"));
        getIntent().putExtra("unity", cmdLine);

        mUnityPlayer = new UnityPlayer(this, this);
        setContentView(mUnityPlayer);
        mUnityPlayer.requestFocus();
    }
    protected String updateUnityCommandLineArguments(String cmdLine)
    {
        return cmdLine;
    }
    @Override protected void onNewIntent(Intent intent){
        // To support deep linking, we need to make sure that the client can get access to
        // the last sent intent. The clients access this through a JNI api that allows them
        // to get the intent set on launch. To update that after launch we have to manually
        // replace the intent with the one caught here.
        setIntent(intent);
        mUnityPlayer.newIntent(intent);
    }
    @Override protected void onStop()
    {
        super.onStop();

        if (!MultiWindowSupport.getAllowResizableWindow(this))
            return;

        mUnityPlayer.pause();
    }
    @Override protected void onStart()
    {
        super.onStart();

        if (!MultiWindowSupport.getAllowResizableWindow(this))
            return;

        mUnityPlayer.resume();
    }
    // Quit Unity
    @Override protected void onDestroy (){
        mUnityPlayer.destroy();
        super.onDestroy();
    }

    // Pause Unity
    @Override protected void onPause(){
        super.onPause();

        if (MultiWindowSupport.getAllowResizableWindow(this))
            return;

        mUnityPlayer.pause();
    }

    // Resume Unity
    @Override protected void onResume(){
        super.onResume();

        if (MultiWindowSupport.getAllowResizableWindow(this))
            return;

        mUnityPlayer.resume();
    }

    // Low Memory Unity
    @Override public void onLowMemory(){
        super.onLowMemory();
        mUnityPlayer.lowMemory();
    }

    // Trim Memory Unity
    @Override public void onTrimMemory(int level){
        super.onTrimMemory(level);
        if (level == TRIM_MEMORY_RUNNING_CRITICAL)
        {
            mUnityPlayer.lowMemory();
        }
    }

    // This ensures the layout will be correct.
    @Override public void onConfigurationChanged(Configuration newConfig){
        super.onConfigurationChanged(newConfig);
        mUnityPlayer.configurationChanged(newConfig);
    }

    // Notify Unity of the focus change.
    @Override public void onWindowFocusChanged(boolean hasFocus){
        super.onWindowFocusChanged(hasFocus);
        mUnityPlayer.windowFocusChanged(hasFocus);
    }


    // For some reason the multiple keyevent type is not supported by the ndk.
    // Force event injection by overriding dispatchKeyEvent().
    @Override public boolean dispatchKeyEvent(KeyEvent event){
        if (event.getAction() == KeyEvent.ACTION_MULTIPLE)
            return mUnityPlayer.injectEvent(event);
        return super.dispatchKeyEvent(event);
    }

    // Pass any events not handled by (unfocused) views straight to UnityPlayer
    @Override public boolean onKeyUp(int keyCode, KeyEvent event)     { return mUnityPlayer.injectEvent(event); }
    @Override public boolean onKeyDown(int keyCode, KeyEvent event)   { return mUnityPlayer.injectEvent(event); }
    @Override public boolean onTouchEvent(MotionEvent event)          { return mUnityPlayer.injectEvent(event); }
    /*API12*/ public boolean onGenericMotionEvent(MotionEvent event)  { return mUnityPlayer.injectEvent(event); }

    @Override
    public void onUnityPlayerUnloaded() {
        moveTaskToBack(true);
    }

    @Override
    public void onUnityPlayerQuitted() {

    }
    //</editor-fold>
}
